package UI;

import java.awt.*;
import java.io.File;

import javax.swing.*;
import javax.swing.filechooser.FileSystemView;

import client.ClientDirectory;
import client.MessageHandler;
import dataContracts.SharedFile;

public class UIbuilder {
	
	//FRAME (PARENT UI OBJECT)
	public JFrame lanyard;
	public JFrame config;
	
	
	//COMMUNICATION OBJECTS FOR SERVER
	public JTextArea serverLogTextBox;
	public JTextField broadcastText;
	public JMenu sync;
	public JButton syncButton;
	
	//METADATA INFORMATION
	public JTextField fileName;
	public JTextField owner;
	public JTextField project;
	public JTextField tags;
	public JTextArea comments;
	
	//SPLIT PANE OBJECT
	public JSplitPane sp;
	public JPanel filePane;
	
	//USER INTERFACE VARIABLES
	public ClientDirectory cd;
	public UI listener;
	public MessageHandler mh;
	public Component active = null;
	
	//CONSTANTS
	private static final Color bgCOLOR = new Color(239,240,240);
	private static final Color highlightCOLOR = new Color(229,230,230);
	
	//CONSTRUCTOR
	
	public UIbuilder(ClientDirectory cd, UI ui, MessageHandler mh){
		this.cd = cd;			//Client Directory associated to this UI
		this.listener = ui;		//Listener Class
		this.mh = mh;			//Message Handler
	}
	
	
	//BUILDER METHODS
	
	// Frame
	public JFrame makeFrame(int x, int y, String title, String name, ImageIcon logo){
		
		lanyard = new JFrame();
        
    	//Application Attributes
        lanyard.setSize(x,y);
        lanyard.setLayout(new GridBagLayout());
        lanyard.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        lanyard.setIconImage(normalizeButton(logo).getImage());
        lanyard.setTitle(title);
        lanyard.setJMenuBar(makeMenuBar());	//add menu bar
        lanyard.setName(name);						//provide object with a name
		
		return lanyard;
		
	}
	
	public JFrame makeConfig(int x, int y, String title, String name, ImageIcon logo){
		
		
		
		return config;
		
	}
	
    // MENU BAR of frame
    private JMenuBar makeMenuBar(){
		
    	JMenuItem item;
    	JMenuBar menuBar;
    	int shortCutMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
 
    	//core element
        menuBar = new JMenuBar();
        
        //file menu
        JMenu file = new JMenu("File");
        file.setMnemonic('F');
        	//exit Item (cmd-x)
        	item = new JMenuItem("Exit");
        	item.setAccelerator(KeyStroke.getKeyStroke('x', shortCutMask));
        	item.setMnemonic('x');
        	item.addActionListener(listener);
        	file.add(item);
        
        //edit menu
        JMenu edit = new JMenu("Edit");
        edit.setMnemonic('E');
        //copy Item (cmd-c)
    		item = new JMenuItem("Add");
    		item.setAccelerator(KeyStroke.getKeyStroke('A', shortCutMask, false));
    		item.setMnemonic('A');
    		item.addActionListener(listener);
    		edit.add(item);
    	//paste Item (cmd-p)
       		item = new JMenuItem("Del");
    		item.setAccelerator(KeyStroke.getKeyStroke('D', shortCutMask, false));
    		item.setMnemonic('D');
    		item.addActionListener(listener);
    		edit.add(item);
    		        
        sync = new JMenu("Sync");
        sync.setMnemonic('y');
        //sync item (cmd-s)
       		item = new JMenuItem("Sync");
			item.setAccelerator(KeyStroke.getKeyStroke('S', shortCutMask, false));
			item.setMnemonic('S');
			item.addActionListener(mh.new IsEqual());
			sync.add(item);        
        //refresh
			item = new JMenuItem("Refresh");
			item.setAccelerator(KeyStroke.getKeyStroke('R', shortCutMask, false));
			item.setMnemonic('R');
			item.addActionListener(listener);
			sync.add(item);
		//connect
			item = new JMenuItem("Connect");
			item.setAccelerator(KeyStroke.getKeyStroke('T', shortCutMask, false));
			item.setMnemonic('h');
			item.addActionListener(mh.new Connect());
			sync.add(item);
			
			
        JMenu help = new JMenu("Help");	   
        help.setMnemonic('H');
        //about item (cmd-a)	
        	item = new JMenuItem("About");
			item.setAccelerator(KeyStroke.getKeyStroke('T', shortCutMask, false));
			item.setMnemonic('T');
			item.addActionListener(listener);
			help.add(item);

        JMenu config = new JMenu("Config");
        config.setMnemonic('C');
        //config item (cmd-c)
			item = new JMenuItem("Config");
        	item.setAccelerator(KeyStroke.getKeyStroke('C', shortCutMask, false));
			item.setMnemonic('C');
			item.addActionListener(listener);
			config.add(item);        	
			
			
        
		//add to bar	
        menuBar.add(file);
        menuBar.add(edit);
        menuBar.add(sync);
        menuBar.add(config);
        menuBar.add(help);
    	
    	return menuBar;
    	
    }
	
    public JToolBar makeToolBar(int Width){
        
    	final int margin = 2;		//for toolbar margin 
    	
    	//Icon instantiations
        ImageIcon syncIcon = normalizeButton(new ImageIcon("images/sync.png"));
        ImageIcon trashIcon = normalizeButton(new ImageIcon("images/trash.png"));
        ImageIcon addIcon = normalizeButton(new ImageIcon("images/addfile.png"));
        
        //BAR
    	JToolBar toolBar = new JToolBar();
    	//Bar Attributes
    		toolBar.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0));
        	toolBar.setMargin(new Insets(margin, margin, margin, margin));
        	toolBar.setFloatable(false);
        	toolBar.setSize(Width, 0);
    	
        //Add Add Button
        JButton addButton = new JButton("Add");
        	addButton.setIcon(addIcon);
        	addButton.setRolloverEnabled(true);
        	addButton.setToolTipText("Add");
        	addButton.addActionListener(listener);
        	
    	//Sync Button
        syncButton = new JButton();
        //Sync Button attributes
        	syncButton.setIcon(syncIcon);
        	syncButton.setRolloverEnabled(true);
        	syncButton.setToolTipText("Sync");
        	syncButton.addActionListener(mh.new IsEqual());
        	
        //Delete Button
        JButton trashButton = new JButton("Del");
        	trashButton.setIcon(trashIcon);
        	trashButton.setRolloverEnabled(true);
        	trashButton.setToolTipText("Delete File");
        	trashButton.addActionListener(listener);
        	
        //add the items	
        toolBar.add(addButton);	
        toolBar.add(trashButton);
        toolBar.addSeparator();
        toolBar.add(syncButton);
        
        
        
        return toolBar;
    
    }
    
    //BUILD THE SPLITPANE -------------------------
    
    public JSplitPane makeSplitPane(int Width){ 
    	
    	sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, initLeftPane(), initRightPane());
    		sp.setOneTouchExpandable(true);
    		sp.setDividerLocation(Width-350);
    	
    	return sp;
    	
    }
    
    //LEFT PANE (FILES)
    private JScrollPane initLeftPane(){
    	
    	JScrollPane pane; 
    	
    	filePane = new JPanel(new GridBagLayout());
			filePane.setBackground(bgCOLOR);
			filePane.setBorder(BorderFactory.createTitledBorder("Files"));
	    
		placeFiles();
		
    	pane = new JScrollPane(filePane);

    	return pane;
    	
    }
    
    //iterates through cd.files collection and creates a file pane for each entry
    private void placeFiles(){
    	
    	GridBagConstraints c;
    	
		c = setConstraints(0, 0, 1, 1, GridBagConstraints.NORTHWEST, new Insets(2, 2, 2, 2), GridBagConstraints.HORIZONTAL);
    	c.gridwidth = GridBagConstraints.REMAINDER;
	     
	    for(SharedFile f : cd.files){
	    	filePane.add(initFileEntry(f), c);
	    	c.gridy++;
	    }
    }
    
    public void redrawLeftPane(){
    	//pull all files from the pane
    	filePane.removeAll();
    	
    	//reset MetaData area
    	active = null;
    	updateMetaData();
    	
    	//add file list back
    	placeFiles();
    	
    	//force a redraw out of queue
    	filePane.updateUI();
    }
    
    //RIGHT PANEL (FILE METADATA)
    private JScrollPane initRightPane(){
    	
    	JScrollPane pane;
    	JPanel panel;
    	GridBagConstraints c;
    	
    	int colOne = 0;
    	int colTwo = 1;
    	
    	String[] labels = {"File Name:", "Owner:","Project:","Tags:"};
    	
    	panel = new JPanel(new GridBagLayout());
    		panel.setBackground(bgCOLOR);
    		panel.setBorder(BorderFactory.createTitledBorder("File Information"));
    	
    	//LABELS
    	c = setConstraints(colOne, 0, 0, 0, GridBagConstraints.NORTHWEST, new Insets(5, 5, 5, 5), GridBagConstraints.HORIZONTAL);
    	c.gridwidth = 1;

    	for(int i = 0; i < labels.length; i++){
        	panel.add(new JLabel(labels[i]), c);
        	c.gridy++;	//next row
    	}
    	
    	//Comments Label
    	panel.add(new JLabel("Comments:"), c);
    	
    	//METADATA TEXTAREAS
    	c = setConstraints(colTwo, 0, 1, 0, GridBagConstraints.NORTHWEST, new Insets(1, 1, 1, 1), GridBagConstraints.HORIZONTAL);
    	c.gridwidth = GridBagConstraints.REMAINDER;
    	
    	fileName = new JTextField();
    	owner = new JTextField();
    	project = new JTextField();
    	tags = new JTextField();
    	comments = new JTextArea(5,0);

    	fileName.setEditable(false);
    	panel.add(fileName, c);
    	c.gridy++;
    	owner.setEditable(false);
    	panel.add(owner, c);
    	c.gridy++;
    	panel.add(project, c);
    	c.gridy++;
    	panel.add(tags, c);
    	c.gridy++;

    	//Comments TextArea
    	c.weighty = 1;
    	
    	comments.setLineWrap(true);
    	comments.setMargin(new Insets(5,5,5,5));
    	panel.add(comments, c);
    	
    	c.gridx = colOne;
    	c.gridy++;
    	panel.add(new JSeparator(SwingConstants.HORIZONTAL), c);
    	
    	c.gridy++;
    	JButton commitButton = new JButton("Commit");
    	commitButton.addActionListener(listener);
    	panel.add(commitButton, c);
    	
    	
    	//SERVER INTERACTION SECTION -----
    	
    	c.gridy++;
    	panel.add(new JSeparator(SwingConstants.HORIZONTAL), c);
    	
    	//Broadcast a message to all clients online
    	c.gridy++;
    	c.gridx = colOne;
    	JLabel broadcastLabel = new JLabel("Message:");
    	panel.add(broadcastLabel, c);
    	
    	c.gridx = colTwo;
    	broadcastText = new JTextField();
    	panel.add(broadcastText, c);
    	
    	c.gridy++;
    	c.gridx = colOne;
    	JButton broadcastButton = new JButton("Send");
    	broadcastButton.addActionListener(mh.new Broadcast());
    	panel.add(broadcastButton, c);
    	
    	c.gridy++;
    	panel.add(new JSeparator(SwingConstants.HORIZONTAL), c);
    	
    	//Server Log TextArea
    	c.weighty= 1;
    	c.gridy++;
    	
    	panel.add(new JLabel("Server Log:"), c);
    	
    	c.gridx = colTwo;
    	serverLogTextBox = new JTextArea(15, 0);
    	serverLogTextBox.setLineWrap(true);
    	serverLogTextBox.setMargin(new Insets(5,5,5,5));
    	serverLogTextBox.setEditable(false);
    	panel.add(serverLogTextBox, c);
    	
    	pane = new JScrollPane(panel);
    	
    	return pane;
    }
    
    private JPanel initFileEntry(SharedFile sf){
    	
    	File f = sf.getFileReference();
		
    	JPanel panel;
    	GridBagConstraints c;
    	
    	panel = new JPanel(new GridBagLayout());
    	panel.addMouseListener(listener);
    	
    	Icon icon = FileSystemView.getFileSystemView().getSystemIcon(f);
    	
        c = setConstraints(0, 0, 1, 0, GridBagConstraints.NORTHWEST, new Insets(20, 20, 20, 20), 0);            
        long size = f.length() / 1024;
        
        panel.setBackground(highlightCOLOR);
        panel.add(new JLabel(icon), c);
        
        c.gridx++;	//next column
        c.anchor = GridBagConstraints.WEST;
        c.weightx++;
        c.insets = new Insets(0,0,0,0);
        panel.add(new JLabel(sf.getName()),c);
        
        c.gridx++; //next col
        c.weightx++;
        c.anchor = GridBagConstraints.EAST;
        c.insets = new Insets(3,3,3,3);
        panel.add(new JLabel(""+size+"KB "), c);
    	
        panel.setName(sf.getFullPath());					//set name to full path of file
        
    	return panel;
    	
    }
    
	//HELPER METHODS
    private ImageIcon normalizeButton(ImageIcon i){
		
        Image image = i.getImage().getScaledInstance(20,20,Image.SCALE_SMOOTH);
        i.setImage(image);    	
    	return i;
    	
    }
    
    public GridBagConstraints gbcHandler(String type){
		
    	GridBagConstraints c;
    	
    	if(type.equals("tb")){
    		c = setConstraints(0,0,1,0,GridBagConstraints.NORTHWEST, new Insets(2,2,2,2), GridBagConstraints.HORIZONTAL);
    		return c; 
    	} else if (type.equals("sp")){
    		c = setConstraints(0,1,1,1,GridBagConstraints.NORTH, new Insets(3,3,3,3), GridBagConstraints.BOTH);
    		return c;
    	} else {
    		//THIS IS GOING TO NEED TO THROW AN ERROR, NULL IS NOT GOING TO FLY
    		return null;
    	}
    	
    }
    
    public void updateMetaData(){
    	
    	if(active!=null){
    		//Find the file based on its full path
    		SharedFile sf = cd.findFile(active.getName());
    	    	
    		//update all meta data about the file
    		fileName.setText(sf.getName());
    		owner.setText(sf.getOwner());
    		project.setText(sf.getProject());
    		tags.setText(sf.getTags());
    		comments.setText(sf.getComments());
    	} else {
    		fileName.setText(null);
    		owner.setText(null);
    		project.setText(null);
    		tags.setText(null);
    		comments.setText(null);
    	}
    		
    		
    }
    
    private GridBagConstraints setConstraints(int x, int y, int wx, int wy, int a, Insets i, int fill){
		
    	GridBagConstraints c = new GridBagConstraints();
    	
    	c.gridx = x;
    	c.gridy = y;
    	c.weightx = wx;
    	c.weighty = wy;
    	c.anchor = a;
    	c.insets = i;
    	c.fill = fill;
    	
    	return c;
 
    }
    
    
}
